
package org.ceteca.explica.server.common.dao;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;

import org.ceteca.explica.core.ExplicaException;
import org.ceteca.explica.core.InterfaceErrors;
import org.ceteca.explica.core.common.BaseVO;
import org.ceteca.explica.core.partners.InterfacePartnersErrors;
import org.ceteca.explica.core.util.OperationResult;
import org.ceteca.explica.core.util.ResultMessage;
import org.ceteca.explica.server.ServerContext;
import org.ceteca.explica.server.util.db.CriteriaBean;
import org.ceteca.explica.server.util.db.HibernateUtil;
import org.ceteca.explica.server.util.db.SQLGenerator;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.impl.CriteriaImpl;




/**
 * @author Juan C. Díaz (juancarlosdiaz@ceteca.net) <br>
 *         Copyright (c) 2009 Fundación Centro Tecnolóxico da Carne
 * 
 * <br>
 * <br>
 *         This program is free software: you can redistribute it and/or modify
 *         it under the terms of the GNU General Public License as published by
 *         the Free Software Foundation, either version 3 of the License, or (at
 *         your option) any later version. <br/>
 *         This program is distributed in the hope that it will be useful, but
 *         WITHOUT ANY WARRANTY 
 *         <br>without even the implied warranty of
 *         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *         General Public License for more details. <br/>
 *         You should have received a copy of the GNU General Public License
 *         along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
public class CommonDAO {

	public CommonDAO() {
	}

	
	public BaseVO getEntity(long id, Class myClass) throws ExplicaException {
		BaseVO result = null;
		Session session = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			result = (BaseVO) session.get(myClass, new Long(id));
		} catch (HibernateException ex) {
			ArrayList<String> lParams = new ArrayList<String>();
			lParams.add("" + id);
			ResultMessage msg = ServerContext.getInstance().getMsgCatalog()
					.newResultMessage(InterfaceErrors.ERR_ENTITY_NOT_FOUND, ex,
							lParams);
			throw new ExplicaException(msg);
		} finally {
			if (session != null)
				session.close();
		}

		return result;
	}

	public OperationResult delEntitiesByCriteria(ArrayList<CriteriaBean> lCriteria, Class myClass){
		OperationResult result= new OperationResult();
		ArrayList lParams = new ArrayList();

		if (lCriteria == null || lCriteria.isEmpty() || myClass == null)
			return null;

		Session session = null;

		try {
			session = HibernateUtil.getSessionFactory().openSession();
			// Build the query statement
			SQLGenerator sqlGen = new SQLGenerator();
			Criteria crit = sqlGen.getSQLCriteria(session, myClass, lCriteria);
			session.delete(crit);
			// Run the query statement
			//Collection r = crit.list();
			
			//crit.
			//if (r != null)
			//	if (!r.isEmpty())
			//		result = (ArrayList) crit.list();

		} catch (HibernateException ex) {
			ex.printStackTrace();
			ServerContext.getInstance().getLogger().error(
					"Error deeleting entities from database", ex);
			System.exit(-1);
		} finally {
			if (session != null)
				session.close();
		}
		return result;
	}
	
	
	public ArrayList getEntities(ArrayList<CriteriaBean> lCriteria,
			Class myClass) throws ExplicaException {
		ArrayList result = null;

		Session session = null;

		try {
			session = HibernateUtil.getSessionFactory().openSession();
			// Build the query statement
			SQLGenerator sqlGen = new SQLGenerator();
			Criteria crit = sqlGen.getSQLCriteria(session, myClass, lCriteria);

			// Run the query statement
			Collection r = crit.list();
			if (r != null)
				if (!r.isEmpty())
					result = (ArrayList) crit.list();

		} catch (HibernateException ex) {

			ServerContext.getInstance().getLogger().error(
					"Error loading entities from database");
			System.exit(-1);
		} finally {
			if (session != null)
				session.close();
		}
		return result;
	}

	
	
	
	
	
	
	
	
	
	
	
	public OperationResult delEntities(ArrayList<Long> lSelEntities,
			Class myClass) throws ExplicaException {

		OperationResult result = new OperationResult();
		ArrayList lParams = new ArrayList();

		if (lSelEntities == null || lSelEntities.isEmpty() || myClass == null)
			return null;

		Session session = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			for (Long i : lSelEntities) {
				Transaction tx = null;
				try {
					tx = session.beginTransaction();
					BaseVO ent = (BaseVO) session.load(myClass, i);
					session.delete(ent);
					tx.commit();

				} catch (HibernateException ex) {
					ex.printStackTrace();
					if (tx != null)
						tx.rollback();
					if (ex.getCause() != null)
						lParams.add(ex.getCause());
					else
						lParams.add(ex.getMessage());
					ResultMessage msg = ServerContext.getInstance()
							.getMsgCatalog().newResultMessage(
									InterfaceErrors.ERR_DELETE_ENTITY, ex,
									lParams);
					// session.close();
					throw new ExplicaException(msg);
				}
			}

		} catch (HibernateException ex) {
			result.addResultMessage(OperationResult.RESULT_ERROR, ServerContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.ERR_HIBERNATE_OPENING_SESSION,
							lParams));
		} finally {
			if (session != null)
//				ServerContext.getInstance().getLogger().debug(
//						"Cerrando sesión despues de borrar entidades");
			session.close();
		}
		if (result.getResult() != OperationResult.RESULT_ERROR)
			result.addResultMessage(OperationResult.RESULT_OK, ServerContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.MSG_DELETE_ENTITY_OK, lParams));
		return result;

	}

	public OperationResult saveEntity(BaseVO entity) throws ExplicaException {

		OperationResult result = new OperationResult();
		if (entity == null) {
			result.addResultMessage(OperationResult.RESULT_ERROR, ServerContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.ERR_SAVE_ENTITY_NULL));
		} else {
			ArrayList lParams = new ArrayList();
			lParams.add(entity.getEntityId());
			Session session = null;
			Transaction tx = null;
			try {
				session = HibernateUtil.getSessionFactory().openSession();
				tx = session.beginTransaction();
				session.saveOrUpdate(entity);
				session.flush();
				tx.commit();
				result.addResultMessage(OperationResult.RESULT_OK,
						ServerContext.getInstance().getMsgCatalog()
								.newResultMessage(
										InterfaceErrors.MSG_SAVE_ENTITY_OK,
										lParams));
			} catch (HibernateException ex) {
				ex.printStackTrace();
				if (tx != null)
					tx.rollback();
				lParams.add(ex.getMessage());
				if (ex.getCause() != null)
					lParams.add(ex.getCause());
				else
					lParams.add(ex.getMessage());
				ResultMessage msg = ServerContext
						.getInstance()
						.getMsgCatalog()
						.newResultMessage(
								InterfacePartnersErrors.ERR_PARTNERS_SAVE_ENTITY,
								ex, lParams);

				throw new ExplicaException(msg);
			} finally {
				if (session != null)
					session.close();

			}

		}
		return result;
	}

	public OperationResult delEntity(BaseVO b) throws ExplicaException {

		OperationResult result = new OperationResult();
		ArrayList lParams = new ArrayList();

		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();

			tx = session.beginTransaction();
			//BaseVO ent = (BaseVO) session.load(b.getClass(), b.getInternalId());
			session.delete(b);
			tx.commit();

		} catch (HibernateException ex) {
			if (tx != null)
				tx.rollback();
			if (ex.getCause() != null)
				lParams.add(ex.getCause());
			else
				lParams.add(ex.getMessage());
			ResultMessage msg = ServerContext.getInstance().getMsgCatalog()
					.newResultMessage(InterfaceErrors.ERR_DELETE_ENTITY, ex,
							lParams);

			throw new ExplicaException(msg);

		} finally {
			if (session != null)
				ServerContext.getInstance().getLogger().debug(
						"Cerrando sesión despues de borrar entidades");
			session.close();
		}
		if (result.getResult() != OperationResult.RESULT_ERROR)
			result.addResultMessage(OperationResult.RESULT_OK, ServerContext
					.getInstance().getMsgCatalog().newResultMessage(
							InterfaceErrors.MSG_DELETE_ENTITY_OK, lParams));
		return result;

	}

	public ArrayList<BaseVO> getEntities(String hql) {
		Session session = null;
		ArrayList<BaseVO> result=new ArrayList<BaseVO>();
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			Query q=session.createQuery(hql);
			result.addAll(q.list());

		} catch (HibernateException ex) {

			ServerContext.getInstance().getLogger().error(
					"Error loading entities from database");
			System.exit(-1);
		} finally {
			if (session != null)
				session.close();
		}
		return result;
	}

}
